package cn.org.rookie;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 控制器方法切面，用于记录方法参数和返回值
 */
@Aspect
@Component
public class MyAspect {

    /**
     * 使用静态ObjectMapper实例，避免重复创建
     */
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 环绕通知，用于记录控制器方法的参数和返回值
     *
     * @param point 连接点
     * @return 方法执行结果
     * @throws Throwable 方法执行可能抛出的异常
     */
    @Around("execution(* cn.org.rookie.*.controller.*.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object target = point.getTarget();
        Logger logger = LoggerFactory.getLogger(target.getClass().getName());
        String methodName = point.getSignature().getName();
        Object[] args = point.getArgs();

        // 记录方法参数
        if (logger.isDebugEnabled() && args != null) {
            for (Object item : args) {
                try {
                    logger.debug("{}方法参数：{}", methodName, MAPPER.writeValueAsString(item));
                } catch (Exception e) {
                    logger.debug("{}方法参数序列化失败：{}", methodName, item.toString());
                }
            }
        }

        // 执行原方法
        Object result = point.proceed();

        // 记录方法返回值
        if (logger.isDebugEnabled()) {
            try {
                logger.debug("{}方法返回：{}", methodName, MAPPER.writeValueAsString(result));
            } catch (Exception e) {
                logger.debug("{}方法返回值序列化失败：{}", methodName, result.toString());
            }
        }

        return result;
    }
}
